package cn.flightcloud.auth.config.spring.security.metadata;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;


public class RefreshSecurityMetadataSource implements RefreshMetadataSource, InitializingBean {

	private Map<RequestMatcher, Collection<ConfigAttribute>> requestMap;

	private Collection<ConfigAttribute> allConfigAttributes;
	
	@Override
	public void afterPropertiesSet() throws Exception {
		load();
	}

	public void load() {
		requestMap = new LinkedHashMap<>();
		String pattern = "/user/**";
		RequestMatcher requestMatcher = new AntPathRequestMatcher(pattern);
		Collection<ConfigAttribute> configAttributes = new ArrayList<>();
		ConfigAttribute configAttribute = new SecurityConfig("admin");
		configAttributes.add(configAttribute);
		requestMap.put(requestMatcher, configAttributes);
	}

	/* (non-Javadoc)
	 * @see cn.flightcloud.auth.config.spring.security.RefreshSecuritySource#refresh()
	 */
	@Override
	public void refresh() {
		load();
	}

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
		for (Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap.entrySet()) {
			if (entry.getKey().matches(request)) {
				return entry.getValue();
			}
		}
		return null;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return this.allConfigAttributes;
	}

	public boolean supports(Class<?> clazz) {
		return FilterInvocation.class.isAssignableFrom(clazz);
	}

}
